package com.umeox.watch.moto.dataservice.services;

import android.app.IntentService;
import android.content.Context;
import android.content.Intent;
import android.os.CountDownTimer;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.os.PowerManager;
import android.text.TextUtils;

import com.umeox.moto.common.log.Logger;
import com.umeox.moto.common.utils.HeartRateControl;
import com.umeox.watch.moto.dataservice.constants.Constants;
import com.umeox.watch.moto.dataservice.db.AppDataBase;
import com.umeox.watch.moto.dataservice.db.model.HeartRate;
import com.umeox.watch.moto.dataservice.utils.LocationHelper;
import com.umeox.watch.moto.dataservice.utils.LogUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * 心率测量服务
 * 接收到服务器测量指令后会启动此服务，
 * 每次测量30S，在多组测量值中取最大值，最小值，平均值进行上传
 */
public class HeartRateMeasureService extends IntentService {
    public static final String TAG = "HeartRateMeasureService";
    private static final String ACTION_FREQUENCY_DETECTION = Constants.APPLICATION_ACTION + ".FREQUENCY_DETECTION";
    private static final String ACTION_CMD_DETECTION = Constants.APPLICATION_ACTION + ".CMD_DETECTION";
    private static final String EXTRA_CMD_CODE = "cmd_code";

    public static final int MILLIS_IN_FUTURE = 12000;
    private static final int MSG_READ_HEART_RATE = 0x10;
    private int limitTime = 31;


    public static final int INVALID_COUNT_MAX = 5;
    private List<Integer> mHeartRateValues = new ArrayList<>();
    private int mInvalidCount;

    private long startTime;
    private long endTime;

    private String mCurrentCMDCode;

    private PowerManager.WakeLock mWakeLock = null;

    public HeartRateMeasureService() {
        super(TAG);
    }

    /**
     * 频率自动测量
     *
     * @param ctx
     */
    public static void freqHeartRateDetection(Context ctx) {
        Intent intent = new Intent(ctx, HeartRateMeasureService.class);
        intent.setAction(ACTION_FREQUENCY_DETECTION);
        ctx.startService(intent);
    }

    /**
     * 用户主动请求测量
     *
     * @param ctx
     * @param code
     */
    public static void cmdHeartRateDetection(Context ctx, String code) {
        Intent intent = new Intent(ctx, HeartRateMeasureService.class);
        intent.setAction(ACTION_CMD_DETECTION);
        intent.putExtra(EXTRA_CMD_CODE,code);
        ctx.startService(intent);
    }


    private final Handler mHandler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            if (msg.what == MSG_READ_HEART_RATE) {
                limitTime--;
                if (limitTime > 0) {
                    final String value = HeartRateControl.getRateValue();
                    final String hrValue = TextUtils.isEmpty(value) ? "0" : value;
                    final int rateValue = Integer.parseInt(hrValue, 16);
                    Logger.i(TAG + "rateValue>>>>>>>>>>>>>>" + rateValue);
                    LogUtils.saveHeartRateMeasureLog( "rateValue>>>>>>>>>>>>>>" + rateValue);
                    if (rateValue != 0) {
                        mInvalidCount = 0;
                        mHeartRateValues.add(rateValue);
                    } else {
                        mInvalidCount++;
                    }
                    Logger.i(TAG + "mInvalidCount>>>>>>>>>>>>>>" + mInvalidCount);
                    LogUtils.saveHeartRateMeasureLog( "mInvalidCount>>>>>>>>>>>>>>" + mInvalidCount);
                    if (mInvalidCount >= INVALID_COUNT_MAX) {
                        mInvalidCount = 0;
                        HeartRateControl.closeRate();
                        HeartRateControl.closeRateForce();
                        //TODO 提示用户正确佩戴
                        //UToast.showLong("Please wear your watch then measure again");
                        return true;
                    }
                    mHandler.sendEmptyMessageDelayed(MSG_READ_HEART_RATE, 1000);
                } else {
                    HeartRateControl.closeRate();
                    if (mHeartRateValues.isEmpty()) {
                        return true;
                    }

                    endTime = System.currentTimeMillis();
                    final Integer max = Collections.max(mHeartRateValues);
                    final Integer min = Collections.min(mHeartRateValues);
                    final int averageValue = getAverageValue();
                    HeartRate heartRate = new HeartRate();
                    heartRate.maxValue = max;
                    heartRate.minValue = min;
                    heartRate.averageValue = averageValue;
                    heartRate.measureTime = endTime;
                    heartRate.isUpload = false;
                    AppDataBase.getInstance().heartRateDao().save(heartRate);

                    LogUtils.saveHeartRateMeasureLog( "本次心率测量完成，cmdCode =" + mCurrentCMDCode + ",averageValue= " + averageValue + ",min=" + min + ",max=" + max);
                    ApiService.uploadHeartRate(mCurrentCMDCode,startTime,endTime,averageValue,min,max);

                    releaseWakeLock();
                }

                return true;
            }
            return false;
        }
    });

    private final CountDownTimer mDownTimer = new CountDownTimer(MILLIS_IN_FUTURE, 1000) {
        @Override
        public void onTick(long millisUntilFinished) {

        }

        @Override
        public void onFinish() {
            mHandler.sendEmptyMessage(MSG_READ_HEART_RATE);
        }
    };

    @Override
    public void onCreate() {
        super.onCreate();
        Logger.i(TAG + ">>>>>>>>>>>>>>HeartRateTestService onCreate<<<<<<<<<<<<<<<<");
        LogUtils.saveHeartRateMeasureLog( ">>>>>>>HeartRateTestService onCreate<<<<<<<<<");
        HandlerThread thread = new HandlerThread("HeartRateTestService");
        thread.start();
        acquireWakeLock();
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        if (intent != null) {
            final String action = intent.getAction();
            if (ACTION_CMD_DETECTION.equals(action)) {
                mCurrentCMDCode = intent.getStringExtra(EXTRA_CMD_CODE);
                HeartRateControl.openRate();
                startTime = System.currentTimeMillis();
                mDownTimer.start();
            } else if (ACTION_FREQUENCY_DETECTION.equals(action)) {

            }
        }
    }


    @Override
    public void onDestroy() {
        Logger.i(TAG + ">>>>>>>>>>>>>>HeartRateMeasureService onDestroy<<<<<<<<<<<<<<<<");
        LogUtils.saveHeartRateMeasureLog( ">>>>>>>HeartRateTestService onDestroy<<<<<<<<<");
        super.onDestroy();
    }

    private int getAverageValue() {
        int sum = 0;
        for (Integer heartRateValue : mHeartRateValues) {
            sum = sum + heartRateValue;
        }
        return sum / mHeartRateValues.size();
    }


    //申请设备电源锁
    private void acquireWakeLock() {
        Logger.i(TAG + ">>>申请设备电源锁");
        LogUtils.saveLog(TAG + ">>>申请设备电源锁");
        if (null == mWakeLock) {
            PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
            if (pm != null) {
                mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, LocationHelper.class.getSimpleName());
            }
            if (null != mWakeLock) {
                mWakeLock.acquire(60 * 1000);
            }
        }
    }

    //释放设备电源锁
    private void releaseWakeLock() {
        if (mWakeLock != null) {
            Logger.w(TAG + ">>>Releasing wakelock");
            try {
                mWakeLock.release();
            } catch (Throwable th) {
                // ignoring this exception, probably wakeLock was already released
            }
        } else {
            // should never happen during normal workflow
            Logger.w(TAG + ">>>Wakelock reference is null");
        }
        mWakeLock = null;
    }
}
